{{!

  Copyright (c) Meta Platforms, Inc. and affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}
{{#import "common/type" as types}}

{{#let export thrift_lib_import = "github.com/facebook/fbthrift/thrift/lib/go/thrift/types"}}
{{#let export thrift_metadata_import = "github.com/facebook/fbthrift/thrift/lib/thrift/metadata"}}

{{#let partial primitive_const_value |value|}}
{{#pragma ignore-newlines}}
  {{#if value.type.byte?}}
int8({{value.integer_value}})
  {{#else if value.type.i16?}}
int16({{value.integer_value}})
  {{#else if value.type.i32?}}
int32({{value.integer_value}})
  {{#else if value.type.i64?}}
int64({{value.integer_value}})
  {{#else if value.type.string?}}
{{value.go_quoted_value}}
  {{#else if value.type.binary?}}
[]byte({{value.go_quoted_value}})
  {{#else if value.type.bool?}}
{{value.nonzero?}}
  {{#else if value.type.float?}}
float32({{#if value.double?}}{{value.double_value}}{{#else}}{{value.integer_value}}.0{{/if}})
  {{#else if value.type.double?}}
float64({{#if value.double?}}{{value.double_value}}{{#else}}{{value.integer_value}}.0{{/if}})
  {{#else if value.type.enum?}}
{{value.type.true_type.go_qualified_name}}
    {{#if value.enum_value?}}
      {{! Known enum value with a name. }}
_{{value.enum_value.name}}
    {{#else}}
      {{! Unknown enum value without a name. }}
({{value.integer_value}})
    {{/if value.enum_value?}}
  {{/if value.type.byte?}}
{{/let partial}}

{{!

  This template defines a constant value representation for a given value.

  All type values are rendered as "concrete" values, except for structs - which
  are rendered as struct pointers. Callers are responsible for dereferencing
  appropriately if needed.

  The following templates have complete type parity:
    * common/constants:const_value (this partial)
    * common/natural_default_value.mustache
    * common/go_zero_value.mustache

  `root_const` is the constant value that is being rendered. It is used to detect
  if struct values can be emitted as references. `root_const` may be null when
  rendering values that aren't part of a named const definition (e.g. field default
  values).
}}
{{#let export partial const_value |value root_const| captures |types primitive_const_value|}}
{{#if (or value.type.primitive? value.type.enum?)}}
{{#partial primitive_const_value value=value}}{{!
}}{{#else if value.type.structured?}}{{!
    Struct value }}
    {{#if (value.referenceable_from? root_const)}}
{{value.owner.go_qualified_name}}{{! No trailing newline
  }}{{#else}}{{! No preceding newline
}}{{value.type.true_type.go_qualified_new_func}}(){{!
    }}{{#if (object.notnull? value.structured_elements)}}{{!
      }}{{#each value.structured_elements as |elem|}}.
    {{elem.field.go_setter_name}}{{#if root_program.compat_setters?}}NonCompat{{/if}}{{!
      }}{{#if elem.value.container?}}(
        {{#partial const_value value=elem.value root_const=root_const}},
    ){{!
      }}{{#else}}{{!
        }}({{#partial const_value value=elem.value root_const=root_const}}){{/if elem.value.container?}}{{!
      }}{{/each}}{{!
    }}{{/if (object.notnull? value.structured_elements)}}{{!
  }}{{/if (value.referenceable_from? root_const)}}{{!
}}{{#else if value.type.map?}}{{!
    Map
}}{{#partial types.go_type type=value.type}}{
  {{#if (object.notnull? value.map_elements)}}
    {{#each value.map_elements as |elem|}}
    {{#partial const_value value=elem.key root_const=root_const}}: {{#partial const_value value=elem.value root_const=root_const}},
    {{/each}}
  {{/if (object.notnull? value.map_elements)}}
}{{!
}}{{#else if value.type.container?}}{{!
    List or set
}}{{#partial types.go_type type=value.type}}{
  {{#if (object.notnull? value.list_elements)}}
    {{#each value.list_elements as |elem|}}
    {{#partial const_value value=elem root_const=root_const}},
    {{/each}}
  {{/if (object.notnull? value.list_elements)}}
}{{!
}}{{/if (or value.type.primitive? value.type.enum?)}}{{!
}}{{/let partial}}
